#include "ccd290.h"


int extract_waveform( waveform_config *wf_cfg, char *binfile ){

    printf("==> calling :%s:%s\n", __FILE__, __func__);

    FILE *fp_bin = fopen(binfile, "rb");

    uint16_t *regs_u16 = (uint16_t*)malloc(sizeof(uint16_t)*wf_cfg->LEN);

    int num_chk = fread(regs_u16, sizeof(uint16_t), wf_cfg->LEN, fp_bin);

    if( num_chk != wf_cfg->LEN ){
        printf("(%s:L:%d) Error in reading binary data: %s\n", __FILE__, __LINE__, binfile);
        printf("@ num_chk       = %d\n", num_chk);
        printf("@ wf_cfg->LEN   = %d\n", wf_cfg->LEN);
        exit(0);
    }

    fclose(fp_bin);

//  ========================================================================
//  调整字节顺序:
//  如果wf_cfg->LEN不是32的整数倍,最后剩余的数据将被丢弃(少于32个),不过这些被丢弃的数据本身也是没用的
    uint16_t tmp[32];
    uint16_t *regs = (uint16_t*)malloc(sizeof(uint16_t)*wf_cfg->LEN);
    int cnt = 0;
    int i = 0;

    // printf("--> adjusting Endian ...\n");
    while( i < wf_cfg->LEN ){
        tmp[31-cnt] = regs_u16[i];
        cnt++;
        i++;

        if( cnt >= 32 ){
            int j, k = 0;
            for( j=i-32; j<i; j++ ){
                regs[j] = tmp[k];
                // printf("(debug) regs[%4d] = %8d\n", j, regs[j]);
                k++;
            }
            cnt = 0;
        }
    }

    // exit(0);

    free(regs_u16);

//  ========================================================================
    char out_file[2048];

    if( strlen(wf_cfg->outfile) > 0 ){
        sprintf(out_file, "%s", wf_cfg->outfile);
    } else {
        if( wf_cfg->WAVE_TYPE == _CCD_OSX_ ){
            sprintf(out_file, "%s/%s_OS_%d.txt", wf_cfg->out_dir, wf_cfg->out_root, wf_cfg->OS_NUM);
        }

        if( wf_cfg->WAVE_TYPE == _V_DRIVE_ ){
            sprintf(out_file, "%s/%s_IMG_%d.txt", wf_cfg->out_dir, wf_cfg->out_root, wf_cfg->IMG_PHASE);   
        }

        if (wf_cfg->WAVE_TYPE == _H_DRIVE_ ){
            sprintf(out_file, "%s/%s_REG_%d.txt", wf_cfg->out_dir, wf_cfg->out_root, wf_cfg->REG_PHASE);
        }
    }


    write_waveform( wf_cfg, regs, out_file );

    free(regs);

    printf("# waveform data has been written into: %s\n\n", out_file);

    return 0;
}

int write_waveform( waveform_config *wf_cfg, uint16_t *regs_u16, char *out_file ){

    printf("==> calling :%s:%s\n", __FILE__, __func__);
    // exit(0);

    int idx0, idx1;
    if( wf_cfg->WAVE_TYPE == _CCD_OSX_ || 
        wf_cfg->WAVE_TYPE == _H_DRIVE_ ){
        idx0 = wf_cfg->S2_idx0;
        idx1 = wf_cfg->S2_idx1;
    } else if( wf_cfg->WAVE_TYPE == _V_DRIVE_ ){
        idx0 = wf_cfg->S5_idx0;
        // idx1 = wf_cfg->S5_idx1;
        idx1 = wf_cfg->S5_idx1 + 200;   // 稍微往后延长2个REG_CLK周期（这个是OK的）
        // idx1 = wf_cfg->S5_idx1 + 2*wf_cfg->SAMP_NUM_PER_REG;   // 稍微往后延长2个REG_CLK周期（这个有问题）
    }

    // printf("idx0 = %10d, idx1 = %10d\n", idx0, idx1);

    int LEN = wf_cfg->S6_idx1*(wf_cfg->N_ROW+1);
    uint16_t *wave = (uint16_t*)malloc(sizeof(uint16_t)*LEN);

    int NROW = wf_cfg->S6_idx1;// + 400;   // 这里不加一个"偏移"的话,组织出来的2维数据(一列对应S1-S6之间的数据)
                                        // 就存在一个系统的"偏移",对波形的叠加处理不利（这个是OK的）

    // int NROW = wf_cfg->S6_idx1 + 4*wf_cfg->SAMP_NUM_PER_REG;    // 这里不加一个"偏移"的话,组织出来的2维数据(一列对应S1-S6之间的数据)
                                                                // 就存在一个系统的"偏移",对波形的叠加处理不利.（这个有问题）

//  这里的NCOL对应保存的波形数据的行数，在这个定义下，输出数据文件中每一列对应一行像元的波形数据
    int NCOL = wf_cfg->N_ROW;              // 这里没有写错！！！！
    
    //  debug
    // printf("# NROW = %d\n", NROW);
    // printf("# NCOL = %d\n", NCOL);
    // exit(0);

    int i, idx;
    int row_idx, col_idx;

    for( i=0; i<wf_cfg->LEN; i++ ){
        col_idx = i / NROW;
        row_idx = i % NROW;
        idx     = row_idx * NCOL + col_idx;

        // if( idx >= LEN ){
        //     printf("# %s:%s@L:%d, idx >= LEN !!!\n", __FILE__, __func__, __LINE__);
        //     printf("# %s:%s@L:%d, LEN   = %d\n", __FILE__, __func__, __LINE__,LEN);
        //     printf("# %s:%s@L:%d, idx   = %d\n", __FILE__, __func__, __LINE__,idx);
        //     printf("# %s:%s@L:%d, NROW  = %d\n", __FILE__, __func__, __LINE__,NROW);
        //     printf("# %s:%s@L:%d, NCOL  = %d\n", __FILE__, __func__, __LINE__,NCOL);
        //     exit(0);
        // }

        if( idx < LEN )
            wave[idx] = regs_u16[i];
    }

    FILE *fp = fopen(out_file, "w");
    int j;
    for( i=0; i<NROW; i++ ){

        // if( i>= 1180*wf_cfg->SAMP_NUM_PER_REG+20 ){  // 临时修改用于限定输出OS波形的范围，这里是跳过pre-scan和光敏区，只输出over-scan
        if( i>= 1180*wf_cfg->SAMP_NUM_PER_REG ){  // 临时修改用于限定输出OS波形的范围，这里是跳过pre-scan和光敏区，只输出over-scan
            if( i>=idx0 && i<idx1 ){
                for( j=0; j<NCOL; j++ ){
                    fprintf(fp, "%8u ", wave[i*NCOL+j]);
                }
                fprintf(fp, "\n");
            }
        }
    
        // for( j=0; j<NCOL; j++ ){
        //     fprintf(fp, "%8u ", wave[i*NCOL+j]);
        // }
        // fprintf(fp, "\n");
    }

    fclose(fp);

    free(wave);

    return 0;
}
